'''
Created on 19/04/2013

@authors: cristian, jean
'''

from flask import Flask, session, redirect, url_for, escape, request, Response
from pm import app
from pm.database import db
from . import jsonifiedview
from .LoginViews import islogged
from pm.models.UsuariosRoles import UsuariosRoles
from pm.models.UsuariosRolesFases import UsuariosRolesFases
from pm.models.Usuarios import Usuarios
from pm.models.Roles import Roles
from pm.views import ensureParams
from sqlalchemy.exc import IntegrityError
from sqlalchemy import or_
from pm.models.Fases import Fases
import json
from StringIO import StringIO


@app.route('/roles/listar', methods=['GET', 'POST']) 
@jsonifiedview
def listarRoles():
    '''
    Lista los Roles existentes en el sistema
    '''
    params = {'GET':request.args, 'POST':request.form}[request.method]
      
    roles = Roles.query
    roles = roles.filter(Roles.nombre.like('%' + params['nombre'] + '%')) if 'nombre' in params else roles
    roles = roles.filter(Roles.descripcion.like('%' + params['descripcion'] + '%')) if 'descripcion' in params else roles 
    roles = roles.filter(Roles.abreviacion.like('%' + params['abreviacion'] + '%')) if 'abreviacion' in params else roles 
    return roles.order_by(Roles.nombre).all()

@app.route('/roles/listardistinctproyecto', methods=['GET', 'POST']) 
@jsonifiedview
def listarRolesDistinctProyecto():
    '''
    Lista los Roles que tiene un usuario y no tiene un 
    @param id_proyecto:identificador del proyecto
    @param id_usuario: identificador del usuario 
    '''
    params = {'GET':request.args, 'POST':request.form}[request.method]
    response = []
    if not ensureParams(params, ['id_proyecto', 'id_usuario']): 
        respon = {"success" : False , "msg" : "Parametros Insuficientes"} 
        return respon  
    id_proyecto=int(str(params['id_proyecto']))
    id_usuario= int(str(params['id_usuario']))
    
    usuarioRolesFases= UsuariosRolesFases.query.filter(UsuariosRolesFases.id_proyecto== id_proyecto).filter(UsuariosRolesFases.activo==True).all()
    usuarioRoles= UsuariosRoles.query.filter(UsuariosRoles.id_usuario==id_usuario).filter(UsuariosRoles.activo==True).filter(UsuariosRoles.id_rol!=2).filter(UsuariosRoles.id_rol!=1).all()
    
    listRoles=[]
    for ur in usuarioRoles:
        rol= Roles.query.filter(Roles.id_rol == ur.id_rol).one()
        if not rol in listRoles:
            listRoles.append(rol)
    
    for ur in usuarioRoles:
        for urf in usuarioRolesFases:
            if (ur.id_usuario_rol==urf.id_usuario_rol):
                rol=Roles.query.filter(Roles.id_rol==ur.id_rol).one()
                listRoles.remove(rol)
            rol=Roles.query.filter(Roles.id_rol==ur.id_rol).one()
            if (rol.id_rol==2):
                listRoles.remove(rol)
    return listRoles

@app.route('/roles/listarrolesusuarioxproyecto', methods=['GET', 'POST']) 
@jsonifiedview
def listarRolesUsuarioxProyecto():
    '''
    Lista los Roles que tiene asociado un usuario en un proyecto 
    '''
    params = {'GET':request.args, 'POST':request.form}[request.method]
    respon = {}
    if not ensureParams(params, ['id_proyecto', 'id_usuario']): 
        respon = {"success" : False , "msg" : "Parametros Insuficientes"} 
        return respon  
    
    id_proyecto=int(str(params['id_proyecto']))
    id_usuario= int(str(params['id_usuario']))
    
    
    usuarioRoles= UsuariosRoles.query.filter(UsuariosRoles.id_usuario==id_usuario).filter(UsuariosRoles.activo==True).filter(UsuariosRoles.id_rol!=2).filter(UsuariosRoles.id_rol!=1).all()
    usuarioRolesFases= UsuariosRolesFases.query.filter(UsuariosRolesFases.id_proyecto == id_proyecto).all()
    
    listRoles=[]
    for ur in usuarioRoles:
        for urf in usuarioRolesFases:
            if(ur.id_usuario_rol==urf.id_usuario_rol):
                rol= Roles.query.filter(Roles.id_rol==ur.id_rol).one()
                rol.activo=urf.activo
                if rol not in listRoles:
                    listRoles.append(rol)
    return listRoles  

@app.route('/roles/listarrolesusuarioxfase', methods=['GET', 'POST']) 
@jsonifiedview
def listarRolesUsuarioxFase():
    '''
    Lista los Roles que tiene asociado un usuario en un proyecto 
    '''
    params = {'GET':request.args, 'POST':request.form}[request.method]
    respon = {}
    if not ensureParams(params, ['id_proyecto', 'id_usuario','id_fase']): 
        respon = {"success" : False , "msg" : "Parametros Insuficientes"} 
        return respon  
    
    id_proyecto=int(str(params['id_proyecto']))
    id_usuario= int(str(params['id_usuario']))
    id_fase= int (str(params['id_fase']))
    
    usuarioRolesFases= UsuariosRolesFases.query.filter(UsuariosRolesFases.id_proyecto == id_proyecto).filter(UsuariosRolesFases.id_fase==id_fase).all()
    usuarioRoles= UsuariosRoles.query.filter(UsuariosRoles.id_usuario==id_usuario).filter(UsuariosRoles.activo==True).filter(UsuariosRoles.id_rol!=2).filter(UsuariosRoles.id_rol!=1).all()
    
    
    listRoles=[]
    for ur in usuarioRoles:
        for urf in usuarioRolesFases:
            if(ur.id_usuario_rol==urf.id_usuario_rol):
                rol= Roles.query.filter(Roles.id_rol==ur.id_rol).one()
                rol.activo=urf.activo_fase
                if rol not in listRoles:
                    listRoles.append(rol)
    return listRoles  


@app.route('/roles/crear', methods=['GET', 'POST']) 
@jsonifiedview
def crearRol():
    '''
        Crea un nuevo Rol 
    '''
    params = {'GET':request.args, 'POST':request.form}[request.method]
    response = {}
  
   
    
    if not ensureParams(params, ['nombre', 'descripcion', 'activo', 'abreviacion']): 
        response = {"success" : False , "msg" : "Parametros Insuficientes"} 
        return response   
             
    try:
        roles = Roles(params['nombre'], params['descripcion'], params['activo'], params['abreviacion'])
        db.session.add(roles)
        db.session.commit()
        response = {"success" : True , "msg" : "Creacion Exitosa!!"}
        return response
    except IntegrityError:
        response = {"success" : False , "msg" : "El Rol ya existe!!"} 
        return response
    except Exception, e:
        db.session.rollback()
        response = {"success" : False , "msg" : "Error en la base de datos!!"}
        return response 


@app.route('/roles/modificar', methods=['GET', 'POST']) 
@jsonifiedview
def modificarRol():
    '''
        Modifica un usuario creado
    '''
    params = {'GET':request.args, 'POST':request.form}[request.method]
    response = {}
    
    
    
    if not ensureParams(params, ['nombre', 'descripcion', 'activo', 'abreviacion']): 
        response = {"success" : False , "msg" : "Parametros Insuficientes"} 
        return response    
          
    try:
        roles = Roles.query.filter(Roles.id_rol == params['id']).update({'nombre':params['nombre'],
        'descripcion':params['descripcion'], 'activo':params['activo'], 'abreviacion':params['abreviacion']})
        db.session.commit()
        response = {"success" : True , "msg" : "Actualizacion exitosa!!"}
        return response
    except IntegrityError:
        response = {"success" : False , "msg" : "Rol ya Existente!!"} 
        return response
    except Exception, e:
        db.session.rollback()
        response = {"success" : False , "msg" : "Error en la base de datos!!"}
        return response 

@app.route('/roles/asignaroltousuario', methods=['GET', 'POST']) 
@jsonifiedview
def asignarRolToUsuario():
    '''
        Metodo que asigna un Rol a un Usuario 
    '''
    params = {'GET':request.args, 'POST':request.form}[request.method]
    response = {}
  
    
    
    if not ensureParams(params, ['id_rol', 'id_usuario', 'activo']): 
        response = {"success" : False , "msg" : "Parametros Insuficientes"} 
        return response   
             
    try:
        usuariosRoles = UsuariosRoles(params['id_rol'], params['id_usuario'], params['activo'])
        db.session.add(usuariosRoles)
        db.session.commit()
        response = {"success" : True , "msg" : "Creacion Exitosa!!"}
        return response
    
    except Exception, e:
        db.session.rollback()
        response = {"success" : False , "msg" : "Error en la base de datos!!"}
        return response 
    
@app.route('/roles/listarbyusuario', methods=['GET', 'POST']) 
@jsonifiedview

def listarRolesByIdUsuario():
    '''
        Lista los Roles asociados a un usuario
    '''
    params = {'GET':request.args, 'POST':request.form}[request.method]
    resp = []
    
    
    id = params ['id'] 
    usuariosRoles = UsuariosRoles.query.filter(UsuariosRoles.id_usuario == id)
    for ur in usuariosRoles:
        roles = Roles.query.filter(Roles.id_rol == ur.id_rol)
        for r in roles:
            r.activo = ur.activo
            resp.append(r)
    return resp

@app.route('/roles/listardistinct', methods=['GET', 'POST']) 
@jsonifiedview
def listarRolesDistinct():
    '''
        Lista los roles que no tiene a un usuario
    '''
    params = {'GET':request.args, 'POST':request.form}[request.method]
    resp = []
    
    id = params ['id'] 
    roles = Roles.query.filter(Roles.activo == True).all()
    resp = roles
    usuariosRoles = UsuariosRoles.query.filter(UsuariosRoles.id_usuario == id)
    for ur in usuariosRoles:
        roles = Roles.query.filter(Roles.id_rol == ur.id_rol).filter(Roles.activo == True)
        for r in roles:
            resp.remove(r)
    return resp

@app.route('/roles/desasignarrol', methods=['GET', 'POST']) 
@jsonifiedview
def desasignarRolaUsuario():
    '''
        Desasigna un rol asignado
    '''
    params = {'GET':request.args, 'POST':request.form}[request.method]
    resp = []
    #if not islogged(): 
        #return resp
    
    id = params ['id']
    
   
    
    usuariosRoles = UsuariosRoles.query.filter(UsuariosRoles.id_usuario_rol == id).one()
    try:
        usuarioRolesFases = UsuariosRolesFases.query.filter(UsuariosRolesFases.id_usuario_rol == usuariosRoles.id_usuario_rol).one()
    except Exception, e:
        band = True
    db.session.delete(usuarioRolesFases)
    db.session.commit()
    
    db.session.delete(usuariosRoles)
    db.session.commit()
    return resp

@app.route('/roles/getusuariosbyroles', methods=['GET', 'POST']) 
@jsonifiedview
def getUsuariosByRoles():
    """
        Trae todos los usuarios que poseen el id rol que se pasa como parametro
    """
    params = {'GET':request.args, 'POST':request.form}[request.method]
    resp = []
    
   
    usuariosRoles = UsuariosRoles.query.filter(UsuariosRoles.id_rol == params ['id'])
    for ur in usuariosRoles:
        usuarios = Usuarios.query.filter(Usuarios.id_usuario == ur.id_usuario)
        for u in usuarios:
            resp.append(u)
    return resp

@app.route('/roles/activarDesactivar', methods=['GET', 'POST']) 
@jsonifiedview
def activarDesactivarUsuarioRol():
    """
        Permite activar o desactivar un ROL Asignado a un Usuario
    """
    params = {'GET':request.args, 'POST':request.form}[request.method]
    response = {}
    
   
    
    if not ensureParams(params,['id_rol','activo','id_usuario']): 
        response ={"success" : False , "msg" : "Parametros Insuficientes"} 
        return response
    
    try:
        if int(str(params['id_rol']))== 2:
            usuariosRo = UsuariosRoles.query.filter(UsuariosRoles.id_rol == params['id_rol']).filter(UsuariosRoles.id_usuario == params['id_usuario']).one()
            if usuariosRo.activo != params['activo']:
                response ={"success" : False , "msg" : "Un lider de proyecto no puede desactivarse"} 
                return response
        if int(str(params['id_rol']))== 1:
            usuariosRo = UsuariosRoles.query.filter(UsuariosRoles.id_rol == params['id_rol']).filter(UsuariosRoles.id_usuario == params['id_usuario']).one()
            if usuariosRo.activo != params['activo']:
                response ={"success" : False , "msg" : "Un administrador no puede desactivarse"} 
                return response
        usuariosRoles = UsuariosRoles.query.filter(UsuariosRoles.id_rol == params['id_rol']).filter(UsuariosRoles.id_usuario == params['id_usuario']).update({'activo':params['activo']})
        db.session.commit()
        response ={"success" : True , "msg" : "Actualizacion exitosa"} 
        return response
    
    except Exception, e:
        db.session.rollback()
        response ={"success" : False , "msg" : "Error en la base de datos"}
        return response 

@app.route('/roles/getestadorelacion', methods=['GET', 'POST']) 
@jsonifiedview
def getestadorelacionusuariorol():
    """
        Permite ver el estado de una relacion usuario rol
    """
    params = {'GET':request.args, 'POST':request.form}[request.method]
    response = {} 
    
    
    if not ensureParams(params,['id_rol','id_usuario']):
        response ={"success" : False , "msg" : "Parametros Insuficientes"} 
        return response
    
    usuariosRoles = UsuariosRoles.query.filter(UsuariosRoles.id_rol == params['id_rol']).filter(UsuariosRoles.id_usuario == params['id_usuario']).one()
    response ={"success" : True , "activo" : usuariosRoles.activo} 
    return response


@app.route('/roles/rolesbyfasedistinct', methods=['GET', 'POST']) 
@jsonifiedview
def getRolesByFaseDistinct():
    """
        Permite listar los roles que un usuario posee en un proyecto y no en una fase dada
        @param id_fase: el id de la fase de la que se desea consultar los datos
        @param id_usuario: el usuario del que se desea consultar los roles
    """
    params = {'GET':request.args, 'POST':request.form}[request.method]
    response = [] 

    if not ensureParams(params,['id_fase','id_usuario']):
        return response
    
    id_fase=int(str(params['id_fase']))
    id_usuario= int(str(params['id_usuario']))
    fase = Fases.query.filter(Fases.id_fase == id_fase).one()
    usuarioRolesFases= UsuariosRolesFases.query.filter(UsuariosRolesFases.activo==True).filter(UsuariosRolesFases.id_proyecto == fase.id_proyecto).filter(or_(UsuariosRolesFases.id_fase!= id_fase,UsuariosRolesFases.id_fase==None)).all()
    usuarioRoles= UsuariosRoles.query.filter(UsuariosRoles.id_usuario==id_usuario).filter(UsuariosRoles.activo==True).all()
    
    listRoles=[]
    for urfAux in usuarioRolesFases:
        for ur in usuarioRoles:
            if ur.id_usuario_rol ==urfAux.id_usuario_rol:
                if urfAux.id_fase!=id_fase:
                    rol= Roles.query.filter(Roles.id_rol == ur.id_rol).one()
                    
                    if not rol in listRoles:
                        if rol.id_rol !=2 and rol.id_rol !=1:
                            listRoles.append(rol)
                            
    listaR=listRoles
    for lr in listRoles:
        rol= Roles.query.filter(Roles.id_rol == lr.id_rol).one()
        for ur in usuarioRoles:
            if lr.id_rol == ur.id_rol:
                for urfAux in usuarioRolesFases:
                    if ur.id_usuario_rol==urfAux.id_usuario_rol and urfAux.id_fase == id_fase:
                        listaR.remove(lr)    
                       
    return listaR
